﻿// DEPENDENCIES:
//   Javascript
//   - jquery
//   - jquery.validate
//   - jquery.form
//   - jquery.metadata

using System;
using System.Data;
using System.Web;
using System.Text;

namespace BigfootWeb.Helpers
{

    /// <summary>
    /// The HTML helper class aids in the raw ouput of html in your views. It has helpers
    /// to output input controls, and all other kind of select tags. This is done in a 
    /// fluid way sort of like jQuery by using the TagBuilder class as the return value of every mehtod
    /// once your are doing composing your html element you simple call ToString and the correctly ouputed 
    /// tag value is returned for inclusing in the view. It also has generic method for Html and Url encode 
    /// string as well as general purpose function for working with HTML.
    /// 
    /// It also has the smarts for dealing with issues like checkbox values not included the post when not checked 
    /// etc. It also makes it easy to create select elements with its options in a more programtically friendly way
    /// including the selection of the proper options when binding your ViewModel etc.
    /// 
    /// You can also use the TagBuilder class to create any HTML tag including the inclussion of Child tags. The HtmlHelper
    /// class however just creates shortcuts to to jumpstart the creation of common tags using the TagBuilder. They then
    /// return the TagBuilder class so you can continue to compose your html output.
    /// 
    /// The TagBuilder is an amazing class that allows you to build a whole field ouput including its label and 
    /// validation requirements in a single line of code.
    /// 
    /// For Example: <%=HtmlHelper.TextBox("Name").Value(123).Label("Amount").ValRequired()%>
    /// </summary>
	public class HtmlHelper
	{

        public HtmlHelper(){}

        public static HtmlHelper Create()
        {
            return new HtmlHelper();
        }

        /// <summary>
        /// Html encode some text
        /// </summary>
        /// <param name="data">The string to encode</param>
        /// <returns>The encoded string</returns>
		public string HtmlEncode(string data)
		{
			return HttpUtility.HtmlEncode(data);
		}

        /// <summary>
        /// Html decode some text
        /// </summary>
        /// <param name="data">The string to decode</param>
        /// <returns>The decoded string</returns>
		public string HtmlDecode(string data)
		{
			return HttpUtility.HtmlDecode(data);
		}

        /// <summary>
        /// Create html output from text by replacing the line feeds etc.
        /// </summary>
        /// <param name="data">The text data to convert</param>
        /// <returns>The Html output</returns>
		public string TextToHtml(string data)
		{
			var n = data;
			n = HtmlEncode(n);
			n = n.Replace("\r\n", "<br />");
			n = n.Replace("\n", "<br />");
			n = n.Replace("\r", "<br />");
			n = n.Replace(Environment.NewLine, "<br />");
			return n;
		}

        /// <summary>
        /// Outputs the start the form element declaration
        /// </summary>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
		public TagBuilder BeginForm()
		{
			return new TagBuilder("form", RenderMode.openTagOnly);
		}

        /// <summary>
        /// Outputs the end of the form element declaration
        /// </summary>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
		public string EndForm()
		{
			return "</form>";
		}

        /// <summary>
        /// Create a div tag
        /// </summary>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
		public TagBuilder DIV()
		{
			return new TagBuilder("div");
		}

        /// <summary>
        /// Creates a div tag and oupts the content provided as the innner html
        /// </summary>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
		public TagBuilder DIV(string content)
		{
			return new TagBuilder("div").InnerHtml(content);
		}

        /// <summary>
        /// Create a span element
        /// </summary>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
		public TagBuilder SPAN()
		{
			return new TagBuilder("span");
		}

        /// <summary>
        /// Creates a span element including the contnet to include the inner html
        /// </summary>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
		public TagBuilder SPAN(string content)
		{
			return new TagBuilder("span").InnerHtml(content);
		}

        /// <summary>
        /// Creates a textbox input
        /// </summary>
        /// <param name="name">The value to assign to the input as the name and id</param>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
		public TagBuilder TextBox(string name)
		{
			return new TagBuilder("input").IDandName(name).type(InputTypes.text);
		}

        /// <summary>
        /// Creates a file input
        /// </summary>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
		public TagBuilder File()
		{
			return new TagBuilder("input").type(InputTypes.file);
		}

        /// <summary>
        /// Creates a file input
        /// </summary>
        /// <param name="name">The value to assign to the input as the name and id</param>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
		public TagBuilder File(string name)
		{
			return new TagBuilder("input").IDandName(name).type(InputTypes.file);
		}

        /// <summary>
        /// Creates a password input
        /// </summary>
        /// <param name="name">The value to assign to the input as the name and id</param>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
		public TagBuilder Password(string name)
		{
			return new TagBuilder("input").IDandName(name).type(InputTypes.password);
		}

        /// <summary>
        /// Creates a textarea input
        /// </summary>
        /// <param name="name">The value to assign to the input as the name and id</param>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
		public TagBuilder TextArea(string name)
		{
			return new TagBuilder("textarea").IDandName(name);
		}

        /// <summary>
        /// Creates a hidden input
        /// </summary>
        /// <param name="name">The value to assign to the input as the name and id</param>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
		public TagBuilder Hidden(string name)
		{
			return new TagBuilder("input").IDandName(name).type(InputTypes.hidden);
		}

        /// <summary>
        /// Creates a submit button
        /// </summary>
        /// <param name="text">The text to assin to the submit button</param>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
		public TagBuilder Submit(string text)
		{
			return Submit(text, true);
		}

        /// <summary>
        /// Creates a submit button and determins weather to validate or not using javascript
        /// </summary>
        /// <param name="text">The text to assin to the submit button</param>
        /// <param name="validate">Determines weather to perform validation or not</param>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
        public TagBuilder Submit(string text, bool validate)
		{
			return Button(text).onclick(JSHelper.Create().Submit(validate, null).CancelEvent().ToString());
		}

        /// <summary>
        /// Creates a submit button and validates certain inputs
        /// </summary>
        /// <param name="text">The text to assin to the submit button</param>
        /// <param name="validateInputNames">Performs validation on the specified inputs</param>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
		public TagBuilder Submit(string text, params string[] validateInputNames)
		{
			return Button(text).onclick(JSHelper.Create().Submit(true, validateInputNames).ToString());
		}

        /// <summary>
        /// Creates a button input
        /// </summary>
        /// <param name="text">The text to include in the button</param>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
		public TagBuilder Button(string text)
		{
			return new TagBuilder("button").InnerText(text);
		}

        /// <summary>
        /// Creates a label for a certain input. You can also alternatively use the .label method on the tagbuilder to add a label to 
        /// an input control while creating the control. The fieldLabel css class is assigned to the label for ease of targeting when formatting.
        /// </summary>
        /// <param name="forName">The input the label belongs to</param>
        /// <param name="labelText">The text to print for the label</param>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
		public TagBuilder Label(string forName, string labelText)
		{
			return new TagBuilder("label").@for(forName).InnerText(labelText).AddClass("fieldLabel");
		}

        /// <summary>
        /// Creates a checkbox input. It correctly deals with the issue related to the false value of a checkbox not being sent to the client 
        /// </summary>
        /// <param name="name">The value to assign to the input as the name and id</param>
        /// <param name="value">The value of the checkbox</param>
        /// <returns>A string with the html for the checkbox</returns>
		public string Checkbox(string name, bool value)
		{
			return Checkbox(name, value, string.Empty, string.Empty);
		}

        /// <summary>
        /// Creates a checkbox input. It correctly deals with the issue related to the false value of a checkbox not being sent to the client 
        /// </summary>
        /// <param name="name">The value to assign to the input as the name and id</param>
        /// <param name="value">The value of the checkbox</param>
        /// <param name="cssclass">The CSS class to assign to the checkbox</param>
        /// <returns>A string with the html for the checkbox</returns>
		public string Checkbox(string name, bool value, string cssclass)
		{
			return Checkbox(name, value, cssclass, string.Empty);
		}

        /// <summary>
        /// Creates a checkbox input. It correctly deals with the issue related to the false value of a checkbox not being sent to the client 
        /// </summary>
        /// <param name="name">The value to assign to the input as the name and id</param>
        /// <param name="value">The value of the checkbox</param>
        /// <param name="cssclass">The CSS class to assign to the checkbox</param>
        /// <param name="label">The label to include the checkbox</param>
        /// <returns>A string with the html for the checkbox</returns>
        public string Checkbox(string name, bool value, string cssclass, string label)
		{
			var chkname = name + "_chk";
			var chk = new TagBuilder("input").IDandName(chkname).type(InputTypes.checkbox);
			var hdn = new TagBuilder("input").IDandName(name).type(InputTypes.hidden);
			// Figure out the value
			if (value) {
				chk.@checked(true);
				hdn.value("true");
			} else {
				chk.@checked(false);
				hdn.value("false");
			}
			// Add the label
			if (string.IsNullOrEmpty(label) == false) {
				chk.Label(label);
			}
			// Add the class if asked
			if (string.IsNullOrEmpty(cssclass) == false) {
				chk.AddClass(cssclass);
			}
			// Wireup events
			chk.onclick("jQuery('#" + name + "').val(this.checked);");
			// Return the value
			return chk.ToString() + hdn;
		}

        /// <summary>
        /// Creates a radio input. It correctly deals with the issue related to the false value of a checkbox not being sent to the client 
        /// </summary>
        /// <param name="name">The value to assign to the input as the name and id</param>
        /// <param name="value">The value of the checkbox</param>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
		public TagBuilder Radio(string name, string value)
		{
			return new TagBuilder("input").type(InputTypes.radio).Name(name).value(value);
		}

	    /// <summary>
	    /// Create a radio list where the value is meant to be a boolean value.
	    /// </summary>
	    /// <param name="name">Element Name</param>
	    /// <param name="value">True or false. These string value will be translated to true: on, yes, true, 1 as needed to identify as true</param>
	    /// <param name="items">Option list</param>
	    public TagBuilder RadioList(string name, bool value, SelectItemList items)
		{
			foreach (SelectItem item in items.ToArray()) {
				var itemBoolValue = false;
				switch (item.Value.ToLower()) {
					case "on":
                        itemBoolValue = true;
						break;
					case "yes":
                        itemBoolValue = true;
						break;
					case "true":
                        itemBoolValue = true;
						break;
					case "1":
						itemBoolValue = true;
						break;
				}
				item.Selected = (itemBoolValue == value);
			}
			return RadioList(name, items);
		}

        /// <summary>
        /// Create a radio list where the value is meant to be a string.
        /// </summary>
        /// <param name="name">Element Name</param>
        /// <param name="value">True or false. These string value will be translated to true: on, yes, true, 1 as needed to identify as true</param>
        /// <param name="items">Option list</param>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
		public TagBuilder RadioList(string name, string value, SelectItemList items)
		{
			if (string.IsNullOrEmpty(value) == false) {
				foreach (var item in items.ToArray()) {
					if (item.Value.ToLower() == value.ToLower())
						item.Selected = true;
				}
			}
			return RadioList(name, items);
		}

        /// <summary>
        /// Create a radio list
        /// </summary>
        /// <param name="name">Element Name</param>
        /// <param name="items">Option list</param>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
        public TagBuilder RadioList(string name, SelectItemList items)
		{
			var parent = new TagBuilder("span").ID(name + "Container");

			var i = 0;
			foreach (var item in items.ToArray()) {
				// Add the radio input
				var radio = parent.AddChild("input").Name(name).type("radio").value(item.Value).ID(name + i);
				// Mark as selected
				if (item.Selected)
					radio.@checked(true);
				// Add the radio label
				parent.AddChild("label").@for(name + i).AddClass("radioLabel").InnerText(item.Text);
				// Make the id unique
				i += 1;
			}

			return parent;
		}

        /// <summary>
        /// Create a select list
        /// </summary>
        /// <param name="name">Name use for the id and name of the html element</param>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
        public TagBuilder Select(string name)
		{
			return new TagBuilder("select").IDandName(name);
		}

        /// <summary>
        /// Create a select list
        /// </summary>
        /// <param name="name">Name use for the id and name of the html element</param>
        /// <param name="options">The list of options to add to the select list</param>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
        public TagBuilder Select(string name, SelectItem[] options)
		{
			return new TagBuilder("select").options(options).IDandName(name);
		}

        /// <summary>
        /// Create a select list
        /// </summary>
        /// <param name="value">The selected value for the list</param>
        /// <param name="options">The list of options to add to the select list</param>
        /// <param name="name">Name use for the id and name of the html element</param>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
        public TagBuilder Select(string name, object value, SelectItem[] options)
		{
			return new TagBuilder("select").options(options, value).IDandName(name);
		}

        /// <summary>
        /// Create an anchor tag
        /// </summary>
        /// <param name="LinkText">The text to use for the link</param>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
		public TagBuilder Link(string LinkText)
		{
			return new TagBuilder("a").InnerText(LinkText).AddAttribute(Attributes.href, "javascript:void(0);");
		}

        /// <summary>
        /// Create an anchor tag that is absolutely positioned over a certain element in the html and is used as 
        /// box if you will around a certain image, block etc.
        /// </summary>
        /// <param name="Title">This is the caption that comes up when you mouse over the link</param>
        /// <param name="top">Distance from the top of the parent element</param>
        /// <param name="left">Distance from the left of the parent element</param>
        /// <param name="height">The height of the link area to cover in case of an image the height of the image</param>
        /// <param name="width">The width of the link area to cover in case of an image the width of the image</param>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
        public TagBuilder LinkOver(string Title, int top, int left, int width, int height)
		{
			return new TagBuilder("a").title(Title).AddAttribute(Attributes.href, "javascript:void(0);").absolute(top, left).size(width, height);
		}

        /// <summary>
        /// Creates an anchor tag. This link does not have text, instead it uses as the background a sprite image
        /// </summary>
        /// <param name="Title">This is the caption that comes up when you mouse over the link</param>
        /// <param name="img">The sprite image</param>
        /// <param name="bgposition">The x y coordinate of the image in the sprite</param>
        /// <param name="width">The width of the sprite image used for this link</param>
        /// <param name="height">The height of the sprite image used for this link</param>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
		public TagBuilder LinkSprite(string Title, string img, string bgposition, int width, int height)
		{
			return new TagBuilder("a").title(Title).AddAttribute(Attributes.href, "javascript:void(0);").sprite(img, bgposition, width, height).inlineblock();
		}

        /// <summary>
        /// Creates an anchor tag. This link does not have text, instead it uses as the background a sprite image. It also has
        /// a rolloever effect with another section of the sprite image. The rollover image site must be the same size
        /// </summary>
        /// <param name="Title">This is the caption that comes up when you mouse over the link</param>
        /// <param name="img">The sprite image</param>
        /// <param name="bgposition">The x y coordinate of the image in the sprite</param>
        /// <param name="width">The width of the sprite image used for this link</param>
        /// <param name="height">The height of the sprite image used for this link</param>
        /// <param name="rolloverposition">The x y coordinate of the image in the sprite for the rollover.</param>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
        public TagBuilder LinkSpriteRollover(string Title, string img, string bgposition, int width, int height, string rolloverposition)
		{
			return new TagBuilder("a").title(Title).AddAttribute(Attributes.href, "javascript:void(0);").spriteRollover(img, bgposition, width, height, rolloverposition).inlineblock();
		}

        /// <summary>
        /// Create an anchor tag
        /// </summary>
        /// <param name="LinkText">The text to use for the link</param>
        /// <param name="href">The url to use for the link</param>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
        public TagBuilder Link(string LinkText, string href)
		{
		    return string.IsNullOrEmpty(href) ? Link(LinkText) : new TagBuilder("a").InnerText(LinkText).AddAttribute(Attributes.href, href);
		}

        /// <summary>
        /// Create an image tag
        /// </summary>
        /// <param name="src">Pass in the url to the image tag</param>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
	    public TagBuilder Image(string src)
		{
			return new TagBuilder("img").src(src);
		}

        /// <summary>
        /// Creates an image tag using a sprite image as the background. To accomplish this it uses a blank image as the src for the image
        /// and it sets the background of the image element to be the xy coordinate of the right image in the sprite
        /// </summary>
        /// <param name="spriteImageUrl">The sprite image</param>
        /// <param name="bgposition">The x y coordinate of the image in the sprite</param>
        /// <param name="width">The width of the sprite image used for this link</param>
        /// <param name="height">The height of the sprite image used for this link</param>
        /// <param name="blankImageUrl">The blank image to use as the source</param>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
		public TagBuilder ImageSprite(string spriteImageUrl, string bgposition, int width, int height, string blankImageUrl)
		{
			return new TagBuilder("img").src(blankImageUrl).sprite(spriteImageUrl, bgposition, width, height);
		}

        /// <summary>
        /// Creates an image tag using a sprite image as the background. To accomplish this it uses a blank image as the src for the image
        /// and it sets the background of the image element to be the xy coordinate of the right image in the sprite. It also adds
        /// a rollover effect to another xy coordinate in the sprite image where the rollover image is. The rolloever image in the sprite
        /// must be the same size as the original image
        /// </summary>
        /// <param name="spriteImageUrl">The sprite image</param>
        /// <param name="bgposition">The x y coordinate of the image in the sprite</param>
        /// <param name="width">The width of the sprite image used for this link</param>
        /// <param name="height">The height of the sprite image used for this link</param>
        /// <param name="rolloverposition">The x y coordinate of the image in the sprite to use for the rollover.</param>
        /// <param name="blankImageUrl">The blank image to use as the source</param>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
        public TagBuilder ImageSpriteRollover(string spriteImageUrl, string bgposition, int width, int height, string rolloverposition, string blankImageUrl)
		{
            return new TagBuilder(blankImageUrl).src("blank.png").spriteRollover(spriteImageUrl, bgposition, width, height, rolloverposition);
		}

        /// <summary>
        /// Create an image tag with a rollover image effect
        /// </summary>
        /// <param name="src">The source of the image to use as the default state</param>
        /// <param name="hoversrc">The url of the image to change to when the mouse rolls over the image</param>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
		public TagBuilder ImageHover(string src, string hoversrc)
		{
			var setsrcscript = "this.src='{0}'";
			return new TagBuilder("img").src(src).onmouseover(string.Format(setsrcscript, hoversrc)).onmouseout(string.Format(setsrcscript, src));
		}

        /// <summary>
        /// Create an image tag sorrounded by an anchor tag.
        /// </summary>
        /// <param name="src">The source of the image to use</param>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
		public TagBuilder ImageLink(string src)
		{
			var lnk = new TagBuilder("a").href("javascript:void(0);").AddClass("pointer");
			lnk.AddChild("img").src(src).AddClass("pointer");
			return lnk;
		}

        /// <summary>
        /// Create an image tag sorrounded by an anchor tag.
        /// </summary>
        /// <param name="src">The source of the image to use</param>
        /// <param name="url">The url to assign to the anchor tag</param>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
        public string ImageLink(string src, string url)
		{
			return ImageLink(src, url, "");
		}

        /// <summary>
        /// Create an image tag sorrounded by an anchor tag.
        /// </summary>
        /// <param name="src">The source of the image to use</param>
        /// <param name="url">The url to assign to the anchor tag</param>
        /// <param name="alt">Assign this alt text to the image</param>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
        public string ImageLink(string src, string url, string alt)
		{
			return new TagBuilder("a").href(url).InnerHtml(Image(src).Alt(alt).ToString()).ToString();
		}

        /// <summary>
        /// Create an image tag sorrounded by an anchor tag with a rollover effect.
        /// </summary>
        /// <param name="src">The source of the image to use as the default state</param>
        /// <param name="hoversrc">The source of the image to use as the hover state</param>
        /// <param name="url">The url to assign to the anchor tag</param>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
		public string ImageLinkHover(string src, string hoversrc, string url)
		{
			return ImageLinkHover(src, hoversrc, url, "");
		}

        /// <summary>
        /// Create an image tag sorrounded by an anchor tag with a rollover effect.
        /// </summary>
        /// <param name="src">The source of the image to use as the default state</param>
        /// <param name="hoversrc">The source of the image to use as the hover state</param>
        /// <param name="url">The url to assign to the anchor tag</param>
        /// <param name="alt">Assign this alt text to the image</param>
        /// <returns>A TagBuilder class to continue to create the tag by adding attr classes etc.</returns>
		public string ImageLinkHover(string src, string hoversrc, string url, string alt)
		{
			return new TagBuilder("a").href(url).InnerHtml(ImageHover(src, hoversrc).Alt(alt).ToString()).ToString();
		}

        /// <summary>
        /// Renders the content only if the speicfied condition is true
        /// </summary>
        /// <param name="condition">The condition that determines weather to render or not. If true it renders</param>
        /// <param name="content">The content to be redered</param>
        /// <returns>A RenderIfBuilder so that you may continue to build your conditional render statement with else etc.</returns>
		public RenderIfBuilder RenderIf(bool condition, string content)
		{
			return new RenderIfBuilder(condition, content);
		}

        /// <summary>
        /// Renders the content only if the speicfied condition is true
        /// </summary>
        /// <param name="condition">The condition that determines weather to render or not. If true it renders</param>
        /// <param name="format">The format to be merged with the supplied value used in the String.Format call</param>
        /// <param name="values">The values to be used in the String.Format call</param>
        /// <returns>A RenderIfBuilder so that you may continue to build your conditional render statement with else etc.</returns>
		public RenderIfBuilder RenderIf(bool condition, string format, params string[] values)
		{
			return new RenderIfBuilder(condition, format, values);
		}

        /// <summary>
        /// Renders only if value given value is not empty
        /// </summary>
        /// <param name="data">IF this data is empty then nothing renders</param>
        /// <returns>A RenderIfBuilder so that you may continue to build your conditional render statement with else etc.</returns>
		public RenderIfBuilder RenderIfNotEmpty(string data)
		{
		    return string.IsNullOrEmpty(data) == false && data.Trim().Length > 0
		               ? new RenderIfBuilder(true, data)
		               : new RenderIfBuilder(false, data);
		}

        /// <summary>
        /// Renders only if value given value is not empty
        /// </summary>
        /// <param name="data">IF this data is empty then nothing renders</param>
        /// <param name="content">The content to render if the data is not empty</param>
        /// <returns>A RenderIfBuilder so that you may continue to build your conditional render statement with else etc.</returns>
	    public RenderIfBuilder RenderIfNotEmpty(string data, string content)
	    {
	        return string.IsNullOrEmpty(data) == false && data.Trim().Length > 0
	                   ? new RenderIfBuilder(true, content)
	                   : new RenderIfBuilder(false, content);
	    }

        /// <summary>
        /// Renders only if value given is not empty
        /// </summary>
        /// <param name="data">IF this data is empty then nothing renders</param>
        /// <param name="content">The content to render using String.Format if the data is not empty</param>
        /// <param name="params">The values to assign to the String.Format</param>
        /// <returns>A RenderIfBuilder so that you may continue to build your conditional render statement with else etc.</returns>
	    public RenderIfBuilder RenderIfNotEmpty(string data, string content, params string[] @params)
	    {
	        return string.IsNullOrEmpty(data) == false && data.Trim().Length > 0
	                   ? new RenderIfBuilder(true, content, @params)
	                   : new RenderIfBuilder(false, content, @params);
	    }

        /// <summary>
        /// Generates an HTML table from a given data table
        /// </summary>
        /// <param name="data">The data to ouput as the html table</param>
        /// <returns>HTML String</returns>
	    public string GenerateHtmlTable(DataTable data)
		{
			var tb = new StringBuilder();
			tb.AppendLine("<table>");

			// Create the headers
			tb.AppendLine("<thead>");
			tb.AppendLine("<tr>");
			foreach (DataColumn col in data.Columns) {
				tb.AppendFormat("<th>{0}</th>{1}", col.ColumnName, "\r\n");
			}
			tb.AppendLine("</tr>");
			tb.AppendLine("</thead>");

			// Create the rows
			tb.AppendLine("<tbody>");
			foreach (DataRow row in data.Rows) {
				tb.AppendLine("<tr>");
				foreach (DataColumn col in data.Columns) {
					tb.AppendLine("<td>");
					if (row.IsNull(col) == false) {
						tb.Append(HttpUtility.HtmlEncode(row[col].ToString()));
					}
					tb.AppendLine("</td>" + "\r\n");
				}
				tb.AppendLine("</tr>");
			}
			tb.AppendLine("</tbody>");
			tb.AppendLine("</table>");

			// Return the data
			return tb.ToString();
		}

        /// <summary>
        /// Builds a Javascript Link tag
        /// </summary>
        /// <param name="filePath">The path to the javascrpt file</param>
        /// <returns>The html for the link element</returns>
		public string JSReference(string filePath)
		{
			return new TagBuilder("script").attr("type", "text/javascript").src(filePath).ToString();
		}

        /// <summary>
        /// Builds a CSS reference tag
        /// </summary>
        /// <param name="filePath">The path to the CSS file</param>
        /// <returns>The html for the CSS reference element</returns>
		public string CSSReference(string filePath)
		{
			return new TagBuilder("link").href(filePath).attr("rel", "stylesheet").attr("type", "text/css").ToString();
		}
        
	}
    
}